package com.christina.engine.state.model;

import com.christina.engine.context.model.UserContext;
import com.christina.engine.context.model.ConversationContext;
import lombok.Builder;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 状态上下文
 * 包含状态处理所需的所有信息
 * 
 * @author Christina
 */
@Data
@Builder
public class StateContext {
    
    /**
     * 会话ID
     */
    private String sessionId;
    
    /**
     * 用户ID
     */
    private Long userId;
    
    /**
     * 用户上下文
     */
    private UserContext userContext;
    
    /**
     * 对话上下文
     */
    private ConversationContext conversationContext;
    
    /**
     * 当前消息
     */
    private String currentMessage;
    
    /**
     * 状态数据
     */
    @Builder.Default
    private Map<String, Object> stateData = new ConcurrentHashMap<>();
    
    /**
     * 状态历史
     */
    @Builder.Default
    private java.util.List<StateHistoryEntry> stateHistory = new java.util.ArrayList<>();
    
    /**
     * 状态开始时间
     */
    private LocalDateTime stateStartTime;
    
    /**
     * 最后活动时间
     */
    private LocalDateTime lastActivityTime;
    
    /**
     * 状态属性
     */
    @Builder.Default
    private Map<String, Object> attributes = new ConcurrentHashMap<>();
    
    /**
     * 错误信息
     */
    private String errorMessage;
    
    /**
     * 重试次数
     */
    @Builder.Default
    private Integer retryCount = 0;
    
    /**
     * 最大重试次数
     */
    @Builder.Default
    private Integer maxRetries = 3;
    
    /**
     * 是否为调试模式
     */
    @Builder.Default
    private Boolean debugMode = false;
    
    /**
     * 获取状态数据
     * 
     * @param key 数据键
     * @param defaultValue 默认值
     * @param <T> 数据类型
     * @return 数据值
     */
    @SuppressWarnings("unchecked")
    public <T> T getStateData(String key, T defaultValue) {
        Object value = stateData.get(key);
        return value != null ? (T) value : defaultValue;
    }
    
    /**
     * 设置状态数据
     * 
     * @param key 数据键
     * @param value 数据值
     */
    public void setStateData(String key, Object value) {
        if (stateData == null) {
            stateData = new ConcurrentHashMap<>();
        }
        stateData.put(key, value);
    }
    
    /**
     * 获取属性值
     * 
     * @param key 属性键
     * @param defaultValue 默认值
     * @param <T> 属性类型
     * @return 属性值
     */
    @SuppressWarnings("unchecked")
    public <T> T getAttribute(String key, T defaultValue) {
        Object value = attributes.get(key);
        return value != null ? (T) value : defaultValue;
    }
    
    /**
     * 设置属性值
     * 
     * @param key 属性键
     * @param value 属性值
     */
    public void setAttribute(String key, Object value) {
        if (attributes == null) {
            attributes = new ConcurrentHashMap<>();
        }
        attributes.put(key, value);
    }
    
    /**
     * 添加状态历史记录
     * 
     * @param fromState 源状态
     * @param toState 目标状态
     * @param reason 转换原因
     */
    public void addStateHistory(String fromState, String toState, String reason) {
        if (stateHistory == null) {
            stateHistory = new java.util.ArrayList<>();
        }
        
        StateHistoryEntry entry = StateHistoryEntry.builder()
                .fromState(fromState)
                .toState(toState)
                .transitionTime(LocalDateTime.now())
                .reason(reason)
                .build();
        
        stateHistory.add(entry);
    }
    
    /**
     * 获取最后的状态历史记录
     * 
     * @return 最后的状态历史记录，如果没有返回null
     */
    public StateHistoryEntry getLastStateHistory() {
        if (stateHistory == null || stateHistory.isEmpty()) {
            return null;
        }
        return stateHistory.get(stateHistory.size() - 1);
    }
    
    /**
     * 检查是否可以重试
     * 
     * @return 是否可以重试
     */
    public boolean canRetry() {
        return retryCount < maxRetries;
    }
    
    /**
     * 增加重试次数
     */
    public void incrementRetryCount() {
        retryCount++;
    }
    
    /**
     * 重置重试次数
     */
    public void resetRetryCount() {
        retryCount = 0;
    }
    
    /**
     * 更新最后活动时间
     */
    public void updateLastActivityTime() {
        lastActivityTime = LocalDateTime.now();
    }
    
    /**
     * 检查状态是否超时
     * 
     * @param timeoutMillis 超时时间（毫秒）
     * @return 是否超时
     */
    public boolean isTimeout(long timeoutMillis) {
        if (timeoutMillis <= 0 || stateStartTime == null) {
            return false;
        }
        
        LocalDateTime timeoutTime = stateStartTime.plusNanos(timeoutMillis * 1_000_000);
        return LocalDateTime.now().isAfter(timeoutTime);
    }
    
    /**
     * 获取状态持续时间（毫秒）
     * 
     * @return 状态持续时间
     */
    public long getStateDurationMillis() {
        if (stateStartTime == null) {
            return 0;
        }
        
        return java.time.Duration.between(stateStartTime, LocalDateTime.now()).toMillis();
    }
    
    /**
     * 清理状态数据
     */
    public void clearStateData() {
        if (stateData != null) {
            stateData.clear();
        }
    }
    
    /**
     * 复制上下文
     * 
     * @return 复制的上下文
     */
    public StateContext copy() {
        return StateContext.builder()
                .sessionId(sessionId)
                .userId(userId)
                .userContext(userContext)
                .conversationContext(conversationContext)
                .currentMessage(currentMessage)
                .stateData(new ConcurrentHashMap<>(stateData != null ? stateData : Map.of()))
                .stateHistory(new java.util.ArrayList<>(stateHistory != null ? stateHistory : java.util.List.of()))
                .stateStartTime(stateStartTime)
                .lastActivityTime(lastActivityTime)
                .attributes(new ConcurrentHashMap<>(attributes != null ? attributes : Map.of()))
                .errorMessage(errorMessage)
                .retryCount(retryCount)
                .maxRetries(maxRetries)
                .debugMode(debugMode)
                .build();
    }
    
    /**
     * 状态历史记录
     */
    @Data
    @Builder
    public static class StateHistoryEntry {
        /**
         * 源状态
         */
        private String fromState;
        
        /**
         * 目标状态
         */
        private String toState;
        
        /**
         * 转换时间
         */
        private LocalDateTime transitionTime;
        
        /**
         * 转换原因
         */
        private String reason;
        
        /**
         * 转换数据
         */
        private Map<String, Object> transitionData;
    }
}